package top.hmtools.wxmp.core.configuration;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import top.hmtools.wxmp.core.access_handle.BaseAccessTokenHandle;
import top.hmtools.wxmp.core.access_handle.DefaultAccessTokenHandle;

/**
 * 全局通用的配置类
 * 
 * @author HyboWork
 *
 */
public class WxmpConfiguration {
	
	final Logger logger = LoggerFactory.getLogger(WxmpConfiguration.class);
	
	/**
	 * 在微信注册的微信公众号应用主键id
	 */
	protected String appid;

	/**
	 * 在微信注册的微信公众号应用秘钥
	 */
	protected String appsecret;

	/**
	 * 收、发数据时的字符编码，缺省 utf-8
	 */
	protected String charset;

	/**
	 * 微信服务器地址
	 */
	protected EUrlServer eUrlServer;
	
	/**
	 * httpclient 连接池配置参数
	 */
	protected int httpMaxTotal;
	
	/**
	 * httpclient 连接池配置参数
	 */
	protected int httpDefaultMaxPerRoute;
	
	/**
	 * 访问微信接口时所需的accessToken工具类名
	 */
	protected Class<? extends BaseAccessTokenHandle> accessTokenHandleClass;
	
	/**
	 * 获取 access token 的工具，根据设置的 top.hmtools.wxmp.core.configuration.WxmpConfiguration.accessTokenHandleClass 生成对应的对象实例
	 */
	private static BaseAccessTokenHandle accessTokenHandle;
	
	/**
	 * 强制使用的accessToken字符串
	 * <br>当本属性被设置为不为空，且不为空字符串时，则强制使用该accessToken字符串，以便于使用某些场景
	 */
	private String forceAccessTokenString;

	
	public String getAppid() {
		return appid;
	}

	public WxmpConfiguration setAppid(String appid) {
		this.appid = appid;
		return this;
	}

	public String getAppsecret() {
		return appsecret;
	}

	public WxmpConfiguration setAppsecret(String appsecret) {
		this.appsecret = appsecret;
		return this;
	}
	
	
	/**
	 * 强制使用的accessToken字符串
	 * <br>当本属性被设置为不为空，且不为空字符串时，则强制使用该accessToken字符串，以便于使用某些场景
	 * @return
	 */
	public String getForceAccessTokenString() {
		return forceAccessTokenString;
	}

	/**
	 * 强制使用的accessToken字符串
	 * <br>当本属性被设置为不为空，且不为空字符串时，则强制使用该accessToken字符串，以便于使用某些场景
	 * @param forceAccessTokenString
	 */
	public void setForceAccessTokenString(String forceAccessTokenString) {
		this.forceAccessTokenString = forceAccessTokenString;
	}

	/**
	 * 获取微信服务器地址
	 * 
	 * @return
	 */
	public EUrlServer geteUrlServer() {
		if (this.eUrlServer == null) {
			this.eUrlServer = EUrlServer.api;
		}
		return eUrlServer;
	}

	/**
	 * 设置微信服务器地址
	 * 
	 * @param eUrlServer
	 */
	public WxmpConfiguration seteUrlServer(EUrlServer eUrlServer) {
		this.eUrlServer = eUrlServer;
		return this;
	}

	/**
	 * 收、发数据时的字符编码，缺省 utf-8
	 * 
	 * @return
	 */
	public String getCharset() {
		if(StringUtils.isBlank(this.charset)){
			this.charset="utf-8";
		}
		return charset;
	}

	/**
	 * 收、发数据时的字符编码，缺省 utf-8
	 * 
	 * @param charset
	 */
	public WxmpConfiguration setCharset(String charset) {
		this.charset = charset;
		return this;
	}


	/**
	 * 访问微信接口时所需的accessToken工具类名
	 * @return
	 */
	public Class<? extends BaseAccessTokenHandle> getAccessTokenHandleClass() {
		if(this.accessTokenHandleClass == null){
			return DefaultAccessTokenHandle.class;
		}else{
			return accessTokenHandleClass;
		}
	}

	/**
	 * 访问微信接口时所需的accessToken工具类名
	 * @param accessTokenHandleClass
	 */
	public void setAccessTokenHandleClass(Class<? extends BaseAccessTokenHandle> accessTokenHandleClass) {
		this.accessTokenHandleClass = accessTokenHandleClass;
	}

	/**
	 * httpclient 连接池配置参数
	 * @return
	 */
	public int getHttpMaxTotal() {
		return httpMaxTotal;
	}

	/**
	 * httpclient 连接池配置参数
	 * @param httpMaxTotal
	 */
	public void setHttpMaxTotal(int httpMaxTotal) {
		this.httpMaxTotal = httpMaxTotal;
	}

	/**
	 * httpclient 连接池配置参数
	 * @return
	 */
	public int getHttpDefaultMaxPerRoute() {
		return httpDefaultMaxPerRoute;
	}

	/**
	 * httpclient 连接池配置参数
	 * @param httpDefaultMaxPerRoute
	 */
	public void setHttpDefaultMaxPerRoute(int httpDefaultMaxPerRoute) {
		this.httpDefaultMaxPerRoute = httpDefaultMaxPerRoute;
	}

	/**
	 * 获取根据设置的 top.hmtools.wxmp.core.configuration.WxmpConfiguration.accessTokenHandleClass 生成对应的对象实例 
	 * <br>已单例化
	 * @return
	 */
	public BaseAccessTokenHandle getAccessTokenHandle() {
		if(accessTokenHandle == null){
			synchronized (BaseAccessTokenHandle.class) {
				if(accessTokenHandle == null){
					try {
						accessTokenHandle = this.getAccessTokenHandleClass().newInstance();
						accessTokenHandle.setWxmpConfiguration(this);
					} catch (InstantiationException | IllegalAccessException e) {
						this.logger.error("创建AccessTokenHandle异常：",e);
					}
				}
			}
		}
		return accessTokenHandle;
	}

	/**
	 * 根据URI获取HTTPS的请求微信公众号接口的URL
	 * @param uri
	 * @return
	 */
	public String getHttpsWxmpUrl(String uri){
		String result = "https://" + this.geteUrlServer().toString() + "/" + uri;
		if (logger.isDebugEnabled()) {
			logger.debug("当前生成的请求URL是：{}", result);
		}
		return result;
	}
	
	/**
	 * 根据URI获取HTTP的请求微信公众号接口的URL
	 * @param uri
	 * @return
	 */
	public String getHttpWxmpUrl(String uri){
		String result = "http://" + this.geteUrlServer().toString() + "/" + uri;
		if (logger.isDebugEnabled()) {
			logger.debug("当前生成的请求URL是：{}", result);
		}
		return result;
	}
	
	/**
	 * 根据URI获取携带access token 的 HTTPS请求微信公众号接口的URL
	 * @param uri
	 * @return
	 */
	public String getHttpsWxmpUrlWithAccessToken(String uri){
		return this.getHttpsWxmpUrl(uri)+"?access_token="+this.getAccessTokenHandle().getAccessTokenString();
	}
	
	/**
	 * 根据URI获取携带access token 的 HTTP请求微信公众号接口的URL
	 * @param uri
	 * @return
	 */
	public String getHttpWxmpUrlWithAccessToken(String uri){
		return this.getHttpWxmpUrl(uri)+"?access_token="+this.getAccessTokenHandle().getAccessTokenString();
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
